package deadlock;

/**
 * * 死锁：
 * * 不同的线程分别占用对方需要的同步资源不放弃，都在等待对方放弃自己需要的同步资源，就形成了线程的死锁。
 * * 写程序时，要避免出现死锁。
 * 诱发死锁的原因：
 * -互斥条件： 互斥条件基本无法被破坏。因为线程需要互斥解决安全问题。
 * -占用且等待： 可以考虑一次性申请所有所需资源，这样就不存在等待问题。
 * -不可抢占（或不可抢夺）：占用部分资源的线程在进一步申请其他资源时，如果申请不到，就主动释放掉自己已经占用的资源。
 * -循环等待： 可以将资源改为线性顺序。申请资源时，先申请序号较小的，这样避免循环等待问题。
 */
public class DeadLockTest {
    public static void main(String[] args) {
        StringBuilder s1 = new StringBuilder();
        StringBuilder s2 = new StringBuilder();

        new Thread(() -> {
            synchronized (s1) {
                s1.append("a");
                s2.append("1");

//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
                synchronized (s2) {
                    s1.append("b");
                    s2.append("2");
                    System.out.println(s1);
                    System.out.println(s2);
                }
            }
        }).start();

        new Thread(() -> {
            synchronized (s2) {
                s1.append("c");
                s2.append("3");

//                try {
//                    Thread.sleep(100);
//                } catch (InterruptedException e) {
//                    throw new RuntimeException(e);
//                }
                synchronized (s1) {
                    s1.append("d");
                    s2.append("4");
                    System.out.println(s1);
                    System.out.println(s2);
                }
            }
        }).start();
    }
}
